package lab.dexter.bbsreader.utils;

import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import lab.dexter.bbsreader.DataHandler;
import lab.dexter.bbsreader.NewSMTHHttpClient;
import lab.dexter.bbsreader.R;

import org.apache.http.HttpEntity;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.ImageView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;


public class ImageGallery extends Activity {
	
	static public Map<String, SoftReference<Bitmap>> imageCache = Collections.synchronizedMap(new HashMap<String,SoftReference<Bitmap>>());
	static public DisplayMetrics metrics = new DisplayMetrics();
	static public int maxDimension;
	static private boolean loading = false;
	static private boolean cancel = false;

	final public static String PARAM_PATH_LIST = "PATH_LIST";
	final public static String PARAM_NAME_LIST = "NAME_LIST";
	
	final public static String BASE_URL = "http://www.newsmth.net";
	
	private List<String> mPathList;
	private List<String> mNameList;
	private Gallery mGallery;
	private GalleryAdapter mGalleryAdapter;
	private Context mContext;
	private ImageView mImageView;
	
    public class MyTask extends AsyncTask<String, Integer, Boolean> {

		@Override
		protected void onCancelled() {
			// TODO Auto-generated method stub
			super.onCancelled();
		}

		@Override
		protected void onPostExecute(Boolean result) {
			super.onPostExecute(result);
			ImageGallery.this.setProgressBarIndeterminateVisibility(false);
			loading = false;
		}

		@Override
		protected void onPreExecute() {
			loading = true;
			ImageGallery.this.setProgressBarIndeterminateVisibility(true);
			super.onPreExecute();
		}

		@Override
		protected void onProgressUpdate(Integer... values) {
			super.onProgressUpdate(values);
			// show pic
			mGalleryAdapter.notifyDataSetChanged();
			if(values[0] == 0) {
				Bitmap bitmap = null;
				if(imageCache.containsKey(mPathList.get(0))) {
					bitmap = imageCache.get(mPathList.get(0)).get();
				}
				if(bitmap == null) {
					// put something else?
					//iv.setImageResource(R.drawable.icon);
				}
				else {
					mImageView.setImageBitmap(bitmap);
				}
			}
		}
		
		private Bitmap shrink(Bitmap orig) {
			int height = orig.getHeight();
			int width = orig.getWidth();
			
			Bitmap bitmapAdj = orig;
			if(Math.max(height, width) > maxDimension) {
				double scaleRate = 1.2 * (double)maxDimension / Math.max(height, width);
				Matrix matrix = new Matrix();
				matrix.postScale((float)scaleRate, (float)scaleRate);
				bitmapAdj = Bitmap.createBitmap(orig, 0, 0, width, height, matrix, true);
			}
			orig = null;
			return bitmapAdj;
		}

		@Override
		protected Boolean doInBackground(String... params) {
			cancel = false;
			for (int i = 0; i < params.length; i++) {
				try {
					final String path = params[i];
					final int index = i;
					if(imageCache.containsKey(path) == false || imageCache.get(path).get() == null) {
						NewSMTHHttpClient.getClient().fetchData(BASE_URL + path, new DataHandler() {

							public void dataProcessor(HttpEntity entity)  throws IOException {
								try {
									InputStream is = entity.getContent();
									Bitmap bmImg = BitmapFactory.decodeStream(is);
									
									if(bmImg == null) { // failed to load image
										return;
									}

									bmImg = shrink(bmImg);

									imageCache.put(path, new SoftReference<Bitmap>(bmImg));

									publishProgress(index);
									if (cancel) {
										cancel = false;
										cancel(true);
									}
								} catch (IllegalStateException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								}
							}
						});
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			return null;
		}
    	
    }

	
	public class GalleryAdapter extends BaseAdapter {
        int GalItemBg;
        private Context mContext;

        public GalleryAdapter(Context c) {
            mContext = c;
            TypedArray typArray = obtainStyledAttributes(R.styleable.GalleryTheme);
            GalItemBg = typArray.getResourceId(R.styleable.GalleryTheme_android_galleryItemBackground, 0);
            typArray.recycle();
        }

        public int getCount() {
            return mPathList.size();
        }

        public Object getItem(int position) {
            return position;
        }

        public long getItemId(int position) {
            return position;
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            ImageView imgView = new ImageView(mContext);
            
            Bitmap bitmap = null;
            if(imageCache.containsKey(mPathList.get(position))) {
            	bitmap = imageCache.get(mPathList.get(position)).get();
            }
            if(bitmap == null) {
            	// load some empty image
            	imgView.setImageResource(R.drawable.icon);
            	if(!loading) {
            		new MyTask().execute(mPathList.toArray(new String[0]));
            	}
            }
            else {
            	imgView.setImageBitmap(bitmap);
            }
            imgView.setLayoutParams(new Gallery.LayoutParams(80, 70));
            imgView.setScaleType(ImageView.ScaleType.FIT_XY);
            imgView.setBackgroundResource(GalItemBg);

            return imgView;
        }
    }

	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
		
		mContext = this;
		
		getWindowManager().getDefaultDisplay().getMetrics(metrics);
		maxDimension = Math.max(metrics.heightPixels, metrics.widthPixels);
		// set it larger?
		
		Intent intent = this.getIntent();
		mPathList = intent.getStringArrayListExtra(PARAM_PATH_LIST);
		mNameList = intent.getStringArrayListExtra(PARAM_NAME_LIST);
		
		this.setContentView(R.layout.image_gallary);
		final ImageView iv = (ImageView)this.findViewById(R.id.image_view);
		mImageView = iv;

		mGalleryAdapter = new GalleryAdapter(this);
		mGallery = (Gallery) findViewById(R.id.image_gallery);
        mGallery.setAdapter(mGalleryAdapter);
        
        

        mGallery.setOnItemClickListener(new OnItemClickListener() {
           public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
        	   Bitmap bitmap = null;
        	   if(imageCache.containsKey(mPathList.get(position))) {
        		   bitmap = imageCache.get(mPathList.get(position)).get();
        	   }
        	   if(bitmap == null) {
        		   // put something else?
        		   //iv.setImageResource(R.drawable.icon);
        	   }
        	   else {
        		   iv.setImageBitmap(bitmap);
        	   }
           }
        });
        
        mImageView.setOnClickListener(new OnClickListener(){
			public void onClick(View v) {
				int position = mGallery.getSelectedItemPosition();
				Toast.makeText(mContext, mNameList.get(position), Toast.LENGTH_SHORT).show();
			}
        });
        
        
	}


	@Override
	public void finish() {
		cancel = true;
		super.finish();
	}
}
